/*
 * Copyright 2018-10-21 8:24:50 The JA-SIG Collaborative. All rights reserved.
 * distributed with thi file and available online at
 */
package com.lap.scp.erp.ao.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.lap.scd.commons.ao.AbstractAO;
import com.lap.scd.commons.constant.RespCode;
import com.lap.scd.commons.core.exception.ManagerException;
import com.lap.scd.commons.page.Page;
import com.lap.scd.commons.page.PageResult;
import com.lap.scd.commons.page.PageUtils;
import com.lap.scd.commons.result.Resp;
import com.lap.scp.erp.ao.AttendanceAO;
import com.lap.scp.erp.bean.AttendanceBean;
import com.lap.scp.erp.core.AttendanceManager;
import com.lap.scp.erp.core.EmployeeManager;
import com.lap.scp.erp.domain.AttendanceDO;
import com.lap.scp.erp.domain.EmployeeDO;
import com.lap.scp.erp.domain.PaymentDO;
import com.lap.scp.erp.query.AttendanceQueryVO;

/**
 * <pre>
 *   默认 出勤记录应用实现类，提供出勤记录相关的流程应用操作、查询等。
 *
 * </pre>
 * 
 * @author 劳水生 Exp
 * @Date 2018-10-21 8:24:50
 * @since 2.0.0
 */
@Service("attendanceAO")
public class DefaultAttendanceAO extends AbstractAO implements AttendanceAO {
	/**
	 * 出勤记录业务操作对象
	 */
	@Resource
	private AttendanceManager attendanceManager;

	@Resource
	private EmployeeManager employeeManager;

	@Override
	public Resp<Integer> insertBatch(AttendanceBean bean) {
		Resp<Integer> resp = new Resp<>();
		try {
			validateInsert(resp, bean);
			if (resp.isSuccess()) {
				List<AttendanceDO> attendList = initAttend(bean);
				List<PaymentDO> list = initPayment(bean);
				attendanceManager.insertBatch(attendList, list);
			}
		} catch (Exception e) {
			resp.putMsg(RespCode.Error, super.getMsg("505", new String[] { e.getLocalizedMessage() }));
			super.writeLog(e);
		}
		return resp;
	}

	/**
	 * <pre>
	 *   <ul>校验新增，逻辑：
	 *   <li>员工不为空
	 *   <li>出勤记录不为空
	 *   <li>出勤日期不为空
	 * 	</ul>
	 * </pre>
	 * 
	 * @param resp
	 * @param bean
	 * @throws ManagerException
	 */
	private void validateInsert(Resp<?> resp, AttendanceBean bean) throws ManagerException {
		List<Date> workDateList = new ArrayList<>();
		List<AttendanceDO> newList = new ArrayList<>();
		if (bean.getEmployeeId() == null) {
			resp.putMsg(getMsg("801"));
		}
		if (bean.getContractId() == null) {
			resp.putMsg(getMsg("806"));
		}
		if (bean.getList() == null || bean.getList().isEmpty()) {
			resp.putMsg(getMsg("802"));
		} else {
			bean.getList().stream().forEach(atte -> {
				if (atte != null && atte.getWorkDate() != null) {
					if (atte.getStartWorkTime().compareTo(atte.getEndWorkTime()) >= 0) {
						resp.putMsg(getMsg("804", new Object[] { atte.getWorkDate() }));
					}
					PaymentDO pay = atte.getPaymentDO();
					if (pay == null || pay.getAmount() == null || pay.getAmount().intValue() < 0) {
						resp.putMsg(getMsg("805"));
					}

					workDateList.add(atte.getWorkDate());
					newList.add(atte);
				}
			});
		}

		if (resp.isSuccess() && !workDateList.isEmpty()) {
			List<AttendanceDO> queryList = attendanceManager.queryByEmployeeIdAndDate(bean.getEmployeeId(),
					workDateList);
			if (queryList != null && !queryList.isEmpty()) {
				for (AttendanceDO query : queryList) {
					if (!validateDate(newList, query)) {
						resp.putMsg(getMsg("803", new Object[] { query.getWorkDate() }));
					}
				}
			}
		}
	}

	/**
	 * <pre>
	 *   . 校验开始时间是否合法
	 * </pre>
	 * 
	 * @param newList
	 * @param query
	 */
	private boolean validateDate(List<AttendanceDO> newList, AttendanceDO query) {
		String qstartTime = query.getStartWorkTime();
		String qendTime = query.getEndWorkTime();
		for (AttendanceDO para : newList) {
			if (query.getWorkDate().equals(para.getWorkDate())) {
				if ((para.getStartWorkTime().compareTo(qstartTime) >= 0
						|| para.getEndWorkTime().compareTo(qstartTime) > 0)
						|| (para.getStartWorkTime().compareTo(qendTime) <= 0
								&& para.getEndWorkTime().compareTo(qendTime) > 0)) {
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * 初始化考勤信息
	 * 
	 * @param bean
	 * @return
	 */
	private List<AttendanceDO> initAttend(AttendanceBean bean) {
		List<AttendanceDO> attendList = new ArrayList<>();
		if (bean != null) {
			List<AttendanceDO> attList = bean.getList();
			for (AttendanceDO atte : attList) {
				if (atte != null && atte.getWorkDate() != null) {
					attendList.add(atte);
					atte.setEmployeeId(bean.getEmployeeId());
					atte.setCreatedBy(bean.getCreatedBy());
					atte.setUpdatedBy(bean.getUpdatedBy());

					// if(atte.getStartWorkTime().compareTo("")>0)
					atte.setStatus(0);// TODO
				}
			}
		}
		return attendList;
	}

	/**
	 * 初始化人工开销信息
	 * 
	 * @param bean
	 * @return
	 * @throws ManagerException
	 */
	private List<PaymentDO> initPayment(AttendanceBean bean) throws ManagerException {
		List<PaymentDO> list = new ArrayList<>();
		if (bean != null) {
			Integer employeeId = bean.getEmployeeId();
			EmployeeDO employeeDO = employeeManager.queryById(employeeId);

			List<AttendanceDO> attList = bean.getList();
			PaymentDO p = null;
			for (AttendanceDO atte : attList) {
				if (atte != null && atte.getWorkDate() != null) {
					p = atte.getPaymentDO();
					list.add(p);
					String uid = UUID.randomUUID().toString();
					p.setSign(uid);
					atte.setSign(uid);

					p.setContractId(bean.getContractId());
					p.setBuyDate(atte.getWorkDate());
					p.setName(employeeDO.getFullName());
					p.setType(bean.getType());
					p.setRemark(atte.getRemark());
					p.setCreatedBy(bean.getCreatedBy());
					p.setUpdatedBy(bean.getUpdatedBy());
				}
			}
		}
		return list;

	}

	@Override
	public Resp<Integer> deleteById(Integer attendanceId) {
		Resp<Integer> resp = new Resp<>();
		try {
			int flag = attendanceManager.deleteById(attendanceId);
			resp.setData(flag);
		} catch (Exception e) {
			resp.putMsg(RespCode.Error, super.getMsg("505", new String[] { e.getLocalizedMessage() }));
			super.writeLog(attendanceId, e);
		}
		return resp;
	}

	@Override
	public Resp<AttendanceDO> queryById(Integer attendanceId) {
		Resp<AttendanceDO> resp = new Resp<>();
		try {
			AttendanceDO attendanceDO = attendanceManager.queryById(attendanceId);
			resp.setData(attendanceDO);
		} catch (Exception e) {
			resp.putMsg(RespCode.Error, super.getMsg("505", new String[] { e.getLocalizedMessage() }));
			super.writeLog(attendanceId, e);
		}
		return resp;
	}

	@Override
	public PageResult<AttendanceDO> queryPage(Page page, AttendanceQueryVO queryVO) {
		PageResult<AttendanceDO> pr = new PageResult<>();
		try {
			List<AttendanceDO> list = attendanceManager.queryPage(page, queryVO);

			PageUtils.copyPage(pr, page);
			pr.setData(list);
		} catch (Exception e) {
			pr.putMsg(RespCode.Error, super.getMsg("505", new String[] { e.getLocalizedMessage() }));
			super.writeLog(new Object[] { page, queryVO }, e);
		}
		return pr;
	}

	@Override
	public Resp<Integer> updateAttendance(AttendanceDO attendanceDO) {
		Resp<Integer> resp = new Resp<>();
		try {
			validateUpdate(resp, attendanceDO);
			if (resp.isSuccess()) {
				this.initUpdate(attendanceDO);

				int flag = attendanceManager.updateAttendance(attendanceDO);
				resp.setData(flag);
			}
		} catch (Exception e) {
			resp.putMsg(RespCode.Error, super.getMsg("505", new String[] { e.getLocalizedMessage() }));
			super.writeLog(attendanceDO, e);
		}
		return resp;
	}

	/**
	 * <pre>
	 *   <p>校验更新考勤信息
	 * </pre>
	 * 
	 * @param resp
	 * @param attendanceDO
	 * @throws ManagerException
	 */
	private void validateUpdate(Resp<?> resp, AttendanceDO attendanceDO) throws ManagerException {
		if (attendanceDO == null) {
			resp.putMsg(getMsg("802"));
		} else {
			if (attendanceDO.getStartWorkTime().compareTo(attendanceDO.getEndWorkTime()) >= 0) {
				resp.putMsg(getMsg("804", new Object[] { attendanceDO.getWorkDate() }));
			}
			PaymentDO pay = attendanceDO.getPaymentDO();
			if (pay == null || pay.getAmount() == null || pay.getAmount().intValue() < 0) {
				resp.putMsg(getMsg("805"));
			}
			if (pay == null || pay.getContractId() == null) {
				resp.putMsg(getMsg("806"));
			}
		}

		if (resp.isSuccess()) {
			List<Date> workDateList = new ArrayList<>(1);
			workDateList.add(attendanceDO.getWorkDate());
			List<AttendanceDO> queryList = attendanceManager.queryByEmployeeIdAndDate(attendanceDO.getEmployeeId(),
					workDateList);
			if (queryList != null && !queryList.isEmpty()) {
				queryList.forEach(query -> {
					if (query.getId() != attendanceDO.getId()) {
						if ((attendanceDO.getStartWorkTime().compareTo(attendanceDO.getEndWorkTime()) >= 0)
								|| (attendanceDO.getStartWorkTime().compareTo(query.getStartWorkTime()) >= 0
										|| attendanceDO.getEndWorkTime().compareTo(query.getStartWorkTime()) > 0)
								|| (attendanceDO.getStartWorkTime().compareTo(query.getEndWorkTime()) <= 0
										&& attendanceDO.getEndWorkTime().compareTo(query.getEndWorkTime()) > 0)) {
							resp.putMsg(getMsg("803", new Object[] { query.getWorkDate() }));
						}
					}
				});
			}
		}
	}

	/**
	 * <pre>
	 *   <li>初始化修改数据
	 * </pre>
	 * 
	 * @param attendanceDO
	 */
	private void initUpdate(AttendanceDO attendanceDO) {
		attendanceDO.setStatus(0);// TODO

		PaymentDO payment = attendanceDO.getPaymentDO();
		if (payment != null) {
			payment.setId(attendanceDO.getPaymentId());
			payment.setBuyDate(attendanceDO.getWorkDate());
			payment.setRemark(attendanceDO.getRemark());
		}

	}

}
